/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package matematikapirma.math;

import java.util.ArrayList;
import java.util.List;
import matematikapirma.CurveAlgorithm;
import matematikapirma.Point;

/**
 *
 * @author Tadas
 */
public class CatmullRomCurveAlgorithm implements CurveAlgorithm {

    public List<Point> calculatePoints(List<Point> initialPoints, boolean open, int steps, int start, int end) {
        List<Point> rpoints = new ArrayList<Point>();
        List<Point> points = new ArrayList<Point>(initialPoints);

        if (open) {
            points.add(0, points.get(0).part(points.get(1), -1.0));
            points.add(points.get(points.size() - 1).part(points.get(points.size() - 2), 1.0));
        } else {
            points.add(0, points.get(points.size() - 1));
            points.add(points.get(1));
            points.add(points.get(2));
        }

        Point q;

        if (steps == 0) {
            steps++;
        }

        for (int i = 2; i < points.size() - 1; i++) {
            for (double j = 0.0; j < 1.0; j += (0.1 / steps)) {
                q = p(points, i, j);
                rpoints.add(q);
            }

            q = p(points, i, 1.0);
            rpoints.add(q);

        }
        return rpoints;
    }

    protected double b(int i, double t) {
        switch (i) {
            case -2:
                return ((-t + 2.0) * t - 1.0) * t / 2.0;
            case -1:
                return (((3.0 * t - 5.0) * t) * t + 2.0) / 2.0;
            case 0:
                return ((-3.0 * t + 4.0) * t + 1) * t / 2.0;
            case 1:
                return ((t - 1.0) * t * t) / 2.0;
        }
        return 0; //we only get here if an invalid i is specified
    }

    protected Point p(List<Point> points, int i, double t) {

        Point p = points.get(0).dot(0.0);
        for (int j = -2; j <= 1; j++) {
            p = p.add(points.get(i + j).dot(b(j, t)));
        }
        return p;
    }

    @Override
    public String toString() {
        return "Catmull-Rom";
    }
}
